import Card from "./Card";
const extends_props = {
	right: {
		get() {
			return this.x + this.width;
		}
	},
	bottom: {
		get() {
			return this.y + this.height;
		}
	},
	centerX: {
		get() {
			return this.x + this.width / 2;
		}
	},
	centerY: {
		get() {
			return this.y + this.height / 2;
		}
	}
};
for (let key in extends_props) {
	Object.defineProperty(
		PIXI.DisplayObject.prototype,
		key,
		extends_props[key]
	);
	if (!PIXI.Rectangle.prototype.hasOwnProperty(key)) {
		Object.defineProperty(
			PIXI.Rectangle.prototype,
			key,
			extends_props[key]
		);
	}
}

PIXI.DisplayObject.prototype.addChildBefore = function(child, before_ele) {
	const index = this.children.indexOf(before_ele);
	if (index !== -1) {
		this.addChildAt(child, index);
	} else {
		this.addChild(child);
	}
};
PIXI.DisplayObject.prototype.addChildAfter = function(child, after_ele) {
	const index = this.children.indexOf(after_ele);
	if (index !== -1) {
		this.addChildAt(child, index + 1);
	} else {
		this.addChild(child);
	}
};
PIXI.DisplayObject.prototype.bindTap = function(event) {
	this.interactive = true;
	this.buttonMode = true;
	this.on("pointertap", event);
};
PIXI.DisplayObject.prototype.maxWidth = function(width) {
	this.width = width;
	this.scale.y = this.scale.x;
};
PIXI.DisplayObject.prototype.maxHeight = function(height) {
	this.height = height;
	this.scale.x = this.scale.y;
};
PIXI.DisplayObject.prototype.maxWidthHeight = function(
	width,
	height,
	cb1,
	cb2
) {
	this.maxWidth(width);
	if (this.height > height) {
		this.maxHeight(height);
		cb2 && cb2();
		return;
	}
	cb1 && cb1();
};

PIXI.DisplayObject.prototype.maxHeightWidth = function(
	height,
	width,
	cb1,
	cb2
) {
	this.maxHeight(height);
	if (this.width > width) {
		this.maxWidth(width);
		cb2 && cb2();
		return;
	}
	cb1 && cb1();
};

function beofreHoverSprite() {
	this.__hover = true;
	[this.bak_texture, this.texture] = [this.texture, this.bak_texture];
}

function afterHoverSprite() {
	if (this.__hover) {
		[this.bak_texture, this.texture] = [this.texture, this.bak_texture];
		this.__hover = false;
	}
}
PIXI.Sprite.prototype.hoverSprite = function(texture) {
	this.interactive = true;
	if (texture) {
		this.bak_texture = texture;
		this.on("pointerdown", beofreHoverSprite);
		this.on("pointerout", afterHoverSprite);
		this.on("pointerup", afterHoverSprite);
		this.on("pointerupoutside", afterHoverSprite);
	} else {
		this.off("pointerdown", beofreHoverSprite);
		this.off("pointerout", afterHoverSprite);
		this.off("pointerup", afterHoverSprite);
		this.off("pointerupoutside", afterHoverSprite);
	}
};
PIXI.Sprite.prototype.hover = PIXI.Graphics.prototype.hover = function(
	down = function() {
		this.tint = 0x999999;
	},
	up = function() {
		this.tint = 0xffffff;
	}
) {
	this.interactive = true;
	this.on("pointerdown", down);
	this.on("pointerout", up);
	this.on("pointerup", up);
	this.on("pointerupoutside", up);
};

class CardSpirte extends PIXI.Sprite {
	static init_loader(loader) {
		const types = [["黑桃", "S"], ["红心", "H"], ["梅花", "C"], ["方块", "D"]];
		const numbers = "2|3|4|5|6|7|8|9|10|J|Q|K|1".split("|");
		types.forEach(([type, res_key]) =>
			numbers.forEach((number, i) => {
				const weight = i + 2;
				loader.add(`${type}_${number}`, `game/${res_key}${weight}.png`);
			})
		);
	}
	constructor(name, resources) {
		name = String(name);
		super(resources[name].texture);
		this.card = Card.getIns(name);
	}
}
PIXI.CardSpirte = CardSpirte;
PIXI.CardListCache = class CardListCache extends WeakMap {
	get(card, resources) {
		if (!this.has(card)) {
			const $card = new CardSpirte(card, resources);
			this.set(card, $card);
			return $card;
		}
		return super.get(card);
	}
};
PIXI.Confirm = class Confirm extends PIXI.Graphics {
	constructor(
		text,
		{
			view_width,
			view_height,
			dialog_texture,
			yes_texture,
			no_texture,
			fontSize,
			fill = 0xffffff,
			parent,
			open = true,
			fontSizeRate,
			can_mask_close,
			close_btm_texture
		}
	) {
		super();
		this.beginFill(0, 0.6);
		this.drawRect(0, 0, view_width, view_height);
		this.endFill(0);
		this.interactive = true;

		const dialog = new PIXI.Sprite(dialog_texture);
		dialog.maxWidthHeight(view_width * 0.7, view_height * 0.7);
		dialog.x = view_width / 2 - dialog.width / 2;
		dialog.y = view_height / 2 - dialog.height / 2;
		this.interactive = true;
		this.addChild(dialog);

		const action_btms = [];
		[
			{
				texture: yes_texture,
				key: "yes",
				close_arg: true
			},
			{
				texture: no_texture,
				key: "no",
				close_arg: false
			}
		].forEach(({ texture, key, close_arg }, i) => {
			let btm;
			if (typeof texture === "string") {
				btm = new PIXI.Graphics();
				btm.beginFill(0x000000, 0.2);
				btm.drawRoundedRect(
					0,
					0,
					dialog.width * 0.4,
					dialog.height * 0.14,
					dialog.height * 0.04
				);
				btm.endFill();
				const text = new PIXI.Text(texture, {
					fontSize: btm.height / 2,
					fill: 0xffffff
				});
				text.x = btm.width / 2 - text.width / 2;
				text.y = btm.height / 2 - text.height / 2;
				btm.addChild(text);
			} else {
				btm = new PIXI.Sprite(texture);
			}
			this[`${key}_button`] = btm;
			btm.maxWidth(dialog.width / 2 * 0.8);
			if (i === 0) {
				btm.x = dialog.x + dialog.width * 0.05;
				btm.y = dialog.y + dialog.height - btm.height * 1.2;
			} else {
				const pre_btm = action_btms[i - 1];
				btm.x = pre_btm.x + pre_btm.width + dialog.width * 0.05;
				btm.y = dialog.y + dialog.height - btm.height * 1.2;
			}
			btm.hover();
			btm.bindTap(() => {
				this.emit(key);
				this.emit("close", close_arg);
			});
			action_btms.push(btm);
			this.addChild(btm);
		});

		this.on("close", function() {
			this.close();
		});
		if (close_btm_texture) {
			const $close_btm = new PIXI.Sprite(close_btm_texture);
			$close_btm.maxWidth(dialog.width * 0.1);
			$close_btm.x = dialog.x + dialog.width - $close_btm.width * 0.5;
			$close_btm.y =
				dialog.y - $close_btm.height + $close_btm.width * 0.5;
			$close_btm.bindTap(() => {
				this.close();
			});
			this.addChild($close_btm);
		}

		if (!isFinite(fontSize)) {
			fontSizeRate = parseFloat(fontSizeRate) || 14;
			fontSize = Math.min(dialog.width, dialog.height) / fontSizeRate;
		}
		let info;
		if (typeof text === "string") {
			info = new PIXI.Text(text, {
				fontSize,
				fill,
				wordWrap: true,
				wordWrapWidth: dialog.width * 0.9
			});
			info.x = view_width / 2 - info.width / 2;
			info.y =
				view_height / 2 -
				info.height / 2 -
				Math.max(...action_btms.map(btm => btm.height));
		} else if (typeof text === "function") {
			info = new PIXI.Container();
			info.x = dialog.x;
			info.y = dialog.y;
			text(info, {
				parent_width: view_width,
				parent_height: view_height,
				dialog_width: dialog.width,
				dialog_height: dialog.height,
				dialog_content_height: dialog.height -
					Math.max(...action_btms.map(btm => btm.height))
			});
		}

		if (info) {
			this.addChild(info);
		}

		if (parent) {
			parent.addChild(this);
		}
		open ? this.open() : this.close();
	}
	close() {
		this.visible = false;
	}
	open() {
		this.visible = true;
	}
};

PIXI.Alert = class Alert extends PIXI.Graphics {
	constructor(
		text,
		{
			align = "center",
			view_width,
			view_height,
			dialog_texture,
			yes_texture,
			fontSize,
			fill = 0xffffff,
			parent,
			open = true,
			fontSizeRate,
			can_mask_close,
			close_btm_texture
		}
	) {
		super();
		this.beginFill(0, 0.6);
		this.drawRect(0, 0, view_width, view_height);
		this.endFill(0);
		this.interactive = true;

		const dialog = new PIXI.Sprite(dialog_texture);
		dialog.maxWidthHeight(view_width * 0.7, view_height * 0.7);
		dialog.x = view_width / 2 - dialog.width / 2;
		dialog.y = view_height / 2 - dialog.height / 2;
		this.addChild(dialog);

		const action_btms = [];
		[
			{
				texture: yes_texture,
				key: "yes",
				close_arg: true
			}
		].forEach(({ texture, key, close_arg }, i) => {
			let btm;
			if (typeof texture === "string") {
				btm = new PIXI.Graphics();
				btm.beginFill(0x000000, 0.2);
				btm.drawRoundedRect(
					0,
					0,
					dialog.width * 0.4,
					dialog.height * 0.14,
					dialog.height * 0.04
				);
				btm.endFill();
				const text = new PIXI.Text(texture, {
					fontSize: btm.height / 2,
					fill: 0xffffff
				});
				text.x = btm.width / 2 - text.width / 2;
				text.y = btm.height / 2 - text.height / 2;
				btm.addChild(text);
			} else {
				btm = new PIXI.Sprite(texture);
			}
			this[`${key}_button`] = btm;
			btm.maxWidth(dialog.width / 2 * 0.8);
			if (i === 0) {
				btm.x = dialog.x + dialog.width / 2 - btm.width / 2;
				btm.y = dialog.y + dialog.height - btm.height * 1.2;
			}
			btm.hover();
			btm.bindTap(() => {
				this.emit(key);
				this.emit("close", close_arg);
			});
			action_btms.push(btm);
			this.addChild(btm);
		});

		this.on("close", function() {
			this.close();
		});
		if (close_btm_texture) {
			const $close_btm = new PIXI.Sprite(close_btm_texture);
			$close_btm.maxWidth(dialog.width * 0.1);
			$close_btm.x = dialog.x + dialog.width - $close_btm.width * 0.5;
			$close_btm.y =
				dialog.y - $close_btm.height + $close_btm.width * 0.5;
			$close_btm.bindTap(() => {
				this.close();
			});
			this.addChild($close_btm);
		}

		if (!isFinite(fontSize)) {
			fontSizeRate = parseFloat(fontSizeRate) || 14;
			fontSize = Math.min(dialog.width, dialog.height) / fontSizeRate;
		}
		let info;
		if (typeof text === "string") {
			info = new PIXI.Text(text, {
				fontSize,
				fill,
				wordWrap: true,
				align,
				wordWrapWidth: dialog.width * 0.9
			});
			info.x = view_width / 2 - info.width / 2;
			info.y =
				view_height / 2 -
				info.height / 2 -
				Math.max(...action_btms.map(btm => btm.height));
		} else if (typeof text === "function") {
			info = new PIXI.Container();
			info.x = dialog.x;
			info.y = dialog.y;
			text(info, {
				parent_width: view_width,
				parent_height: view_height,
				dialog_width: dialog.width,
				dialog_height: dialog.height,
				dialog_content_height: dialog.height -
					Math.max(...action_btms.map(btm => btm.height))
			});
		}

		if (info) {
			this.addChild(info);
		}

		if (parent) {
			parent.addChild(this);
		}
		open ? this.open() : this.close();
	}
	close() {
		this.visible = false;
	}
	open() {
		this.visible = true;
	}
};
PIXI.ScrollContainer = class ScrollContainer extends PIXI.Container {
	constructor({ view_width, view_height, ani_tween }) {
		super();
		this.view_width = view_width;
		this.view_height = view_height;
		this.ani_tween = ani_tween;
		const scrollContainer = (this.scrollContainer = new PIXI.Container());
		this.addChild(scrollContainer);
		const items = (this.items = []);

		// const mask = (this.mask = new PIXI.Graphics());
		// mask
		//   .beginFill(0xffffff, 0.2)
		//   .drawRect(0, 0, this.view_width, this.view_height)
		//   .endFill();

		// this.addChild(mask);
		// scrollContainer.mask = mask;

		this.item_height = 100;

		var mousedown = false;
		var lastPos = null;
		var lastDiff = null;
		var maxVel = 0;

		const onmousemove = e => {
			const originalEvent = e.data.originalEvent;
			var clientY = !originalEvent.touches
				? originalEvent.clientY
				: originalEvent.touches[0].clientY;

			if (mousedown) {
				lastDiff = clientY - lastPos.y;
				lastPos.y = clientY;

				if (-scrollContainer.y < 0) {
					scrollContainer.y += lastDiff / 2;
				} else {
					scrollContainer.y += lastDiff;
				}
			}
		};
		const onmousedown = e => {
			const originalEvent = e.data.originalEvent;
			var clientY = !originalEvent.touches
				? originalEvent.clientY
				: originalEvent.touches[0].clientY;

			mousedown = true;
			// if (scrollTween) scrollTween.kill();
			lastPos = {
				y: clientY
			};
		};

		function onmouseup(e) {
			// if (lastDiff) {
			//   var goY = scrollContainer.y + lastDiff * 10;
			//   var ease = Quad.easeOut;
			//   var time = Math.abs(lastDiff / 150);

			//   if (goY < -items.length * this.item_height + this.view_height) {
			//     goY = -items.length * this.item_height + this.view_height;
			//     ease = Back.easeOut;
			//     time = 0.1 + Math.abs(lastDiff / 150);
			//   }
			//   if (goY > 0) {
			//     goY = 0;
			//     ease = Back.easeOut;
			//     time = 0.1 + Math.abs(lastDiff / 150);
			//   }

			//   if (scrollContainer.y > 0) {
			//     time = 1 + scrollContainer.y / 500;
			//     ease = Elastic.easeOut;
			//   }
			//   if (scrollContainer.y < -items.length * this.item_height + this.view_height) {
			//     time =
			//       1 +
			//       (items.length * this.item_height + this.view_height + scrollContainer.y) /
			//         500;
			//     ease = Elastic.easeOut;
			//   }

			//   scrollTween = TweenMax.to(scrollContainer, time, {
			//     y: goY,
			//     ease: ease
			//   });
			// }

			mousedown = false;
			lastPos = null;
			lastDiff = null;
		}

		this.interactive = true;
		this.mousemove = onmousemove;
		this.mousedown = onmousedown;
		this.mouseup = onmouseup;
		this.touchmove = onmousemove;
		this.touchstart = onmousedown;
		this.touchend = onmouseup;
	}
	hideOffscreenElements() {
		var startIndex = Math.floor(-this.scrollContainer.y / this.item_height);
		var endIndex = Math.floor(
			startIndex + this.view_height / this.item_height
		);

		for (var i = 0; i < this.items.length; i++) {
			var item = this.items[i];
			item.visible = false;
			if (i >= startIndex && i <= endIndex + 1) {
				item.visible = true;
			}
		}
	}
};
